import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../../../core/models/friend_model.dart';
import '../../../core/models/chat_message.dart';
import '../../../core/models/call_invite.dart';
import '../../../core/viewmodels/auth_viewmodel.dart';
import '../../../core/di/service_locator.dart';
import '../../../core/repositories/chat_repository.dart';
import '../../../core/services/websocket_service_rust.dart';
import '../../../core/services/chat_message_storage_service.dart';
import '../../../core/config/app_config.dart';
import '../../../core/services/image_cache_service.dart';
import '../../../shared/widgets/cached_avatar.dart';
import '../../../shared/widgets/markdown_message.dart';
import '../../../shared/widgets/call_invite_dialog.dart';
import '../../../core/utils/error_handler_extension.dart';
import 'video_call_page.dart';
import 'dart:developer' as developer;

class ChatDetailPage extends StatefulWidget {
  final FriendModel friend;

  const ChatDetailPage({
    super.key,
    required this.friend,
  });

  @override
  State<ChatDetailPage> createState() => _ChatDetailPageState();
}

class _ChatDetailPageState extends State<ChatDetailPage> {
  final TextEditingController _messageController = TextEditingController();
  final ScrollController _scrollController = ScrollController();
  final List<ChatMessage> _messages = [];
  bool _isSending = false;
  
  late final WebSocketServiceRust _webSocketService;
  late final ChatMessageStorageService _messageStorageService;
  StreamSubscription<dynamic>? _websocketSubscription;
  String? _currentUserId;
  String? _targetUserId; // 可以是ID或username
  String? _targetUsername; // 好友的用户名
  String? _targetUserIdNum; // 好友的数字ID（字符串形式）
  Set<String> _targetUserIds = {}; // 目标用户的所有可能ID集合（用于匹配）
  Set<String> _currentUserIds = {}; // 当前用户的所有可能ID集合（用于匹配）

  @override
  void initState() {
    super.initState();
    _initializeServices();
    // 延迟初始化，确保context可用
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _loadLocalMessages();
      _setupWebSocketListener();
    });
  }

  void _initializeServices() {
    final serviceLocator = ServiceLocator();
    _webSocketService = serviceLocator.webSocketService;
    _messageStorageService = ChatMessageStorageService(serviceLocator.storageService);
    // 同时保存好友的ID和username，用于匹配消息
    _targetUsername = widget.friend.username;
    _targetUserIdNum = widget.friend.userId.toString();
    // 优先使用数字ID，如果没有则使用username
    _targetUserId = (_targetUserIdNum?.isNotEmpty ?? false) ? _targetUserIdNum : _targetUsername;
    
    // 收集目标用户的所有可能ID（用于匹配消息）
    _targetUserIds = {
      if (_targetUserIdNum != null && _targetUserIdNum!.isNotEmpty) _targetUserIdNum!,
      if (_targetUsername != null && _targetUsername!.isNotEmpty) _targetUsername!,
      if (widget.friend.openId != null && widget.friend.openId!.isNotEmpty) widget.friend.openId!,
    };
    
    developer.log('初始化目标用户: userId=$_targetUserIdNum, username=$_targetUsername, targetUserId=$_targetUserId, targetUserIds=$_targetUserIds', name: 'ChatDetailPage');
  }
  
  void _updateCurrentUserId() {
    final authViewModel = context.read<AuthViewModel>();
    final currentUser = authViewModel.currentUser;
    if (currentUser != null) {
      _currentUserId = currentUser.openId ?? currentUser.username;
      
      // 收集当前用户的所有可能ID（用于匹配消息）
      _currentUserIds = {
        if (currentUser.openId != null && currentUser.openId!.isNotEmpty) currentUser.openId!,
        if (currentUser.username.isNotEmpty) currentUser.username,
        if (currentUser.id > 0) currentUser.id.toString(),
      };
    }
  }

  Future<void> _loadLocalMessages() async {
    _updateCurrentUserId();
    if (_currentUserId == null) return;
    
    try {
      final messages = await _messageStorageService.loadMessages(_currentUserId!);
      // 过滤出与当前好友的聊天消息（使用ID集合进行匹配）
      final filteredMessages = messages.where((msg) {
        // 过滤掉通话邀请消息（message_content_type === 4）和通话取消消息（message_content_type === 5）
        final messageType = msg.messageType;
        if (messageType == 4 || messageType == 5) {
          return false; // 不显示系统消息
        }
        
        // 检查消息内容是否是通话相关消息
        final content = msg.content ?? '';
        if (content.isNotEmpty) {
          try {
            final parsed = jsonDecode(content) as Map<String, dynamic>?;
            if (parsed != null) {
              final type = parsed['type']?.toString();
              if (type == 'call_invite' || type == 'call_cancel') {
                return false; // 不显示通话相关系统消息
              }
            }
          } catch (e) {
            // 不是 JSON，继续处理
          }
        }
        
        if (msg.fromUserId == null || msg.toUserId == null) {
          return false;
        }
        
        final normalizedFromUserId = msg.fromUserId!.trim();
        final normalizedToUserId = msg.toUserId!.trim();
        
        // 检查 from_user_id 或 to_user_id 是否匹配目标用户
        final isFromTarget = _targetUserIds.any((id) => normalizedFromUserId == id.trim());
        final isToTarget = _targetUserIds.any((id) => normalizedToUserId == id.trim());
        
        // 检查 from_user_id 或 to_user_id 是否匹配当前用户
        final isFromMe = _currentUserIds.any((id) => normalizedFromUserId == id.trim());
        final isToMe = _currentUserIds.any((id) => normalizedToUserId == id.trim());
        
        // 消息必须与当前好友相关（发送给好友或从好友接收）
        return (isFromTarget && isToMe) || (isFromMe && isToTarget);
      }).toList();
      
      if (mounted) {
        setState(() {
          _messages.clear();
          _messages.addAll(filteredMessages);
        });
        developer.log('加载本地消息: ${filteredMessages.length} 条', name: 'ChatDetailPage');
        
        // 预加载图片到本地缓存
        _preloadImages(filteredMessages);
      }
    } catch (e) {
      developer.log('加载本地消息失败: $e', name: 'ChatDetailPage');
    }
  }

  /// 预加载消息中的图片和文件到本地缓存
  Future<void> _preloadImages(List<ChatMessage> messages) async {
    try {
      final imageCacheService = ServiceLocator().imageCacheService;
      
      for (final message in messages) {
        // 预加载图片消息（messageType == 2）
        if (message.messageType == 2 && (message.fileUrl != null || message.content.isNotEmpty)) {
          String? imageUrl;
          
          if (message.fileUrl != null && message.fileUrl!.isNotEmpty) {
            imageUrl = message.fileUrl;
          } else if (message.content.isNotEmpty) {
            final trimmedContent = message.content.trim();
            if (trimmedContent.startsWith('http://') || 
                trimmedContent.startsWith('https://') ||
                trimmedContent.startsWith('/api/upload/') ||
                trimmedContent.startsWith('/upload/')) {
              imageUrl = trimmedContent;
            }
          }
          
          if (imageUrl != null && !imageUrl.startsWith('data:image/')) {
            // 在后台预加载图片（不阻塞 UI）
            imageCacheService.preloadImage(imageUrl).catchError((e) {
              developer.log('预加载图片失败: $imageUrl, $e', name: 'ChatDetailPage');
            });
          }
        }
        // 预加载文件消息（messageType == 3）
        else if (message.messageType == 3 && (message.fileUrl != null || message.content.isNotEmpty)) {
          String? fileUrl;
          
          if (message.fileUrl != null && message.fileUrl!.isNotEmpty) {
            fileUrl = message.fileUrl;
          } else if (message.content.isNotEmpty) {
            final trimmedContent = message.content.trim();
            if (trimmedContent.startsWith('http://') || 
                trimmedContent.startsWith('https://') ||
                trimmedContent.startsWith('/api/upload/') ||
                trimmedContent.startsWith('/upload/')) {
              fileUrl = trimmedContent;
            }
          }
          
          if (fileUrl != null) {
            // 在后台预加载文件（不阻塞 UI）
            imageCacheService.preloadFile(fileUrl).catchError((e) {
              developer.log('预加载文件失败: $fileUrl, $e', name: 'ChatDetailPage');
            });
          }
        }
      }
    } catch (e) {
      developer.log('预加载文件异常: $e', name: 'ChatDetailPage');
    }
  }

  void _setupWebSocketListener() {
    // 更新当前用户ID
    _updateCurrentUserId();
    
    // 监听WebSocket消息
    _websocketSubscription = _webSocketService.messageStream.listen(
      (message) {
        developer.log('ChatDetailPage received message from stream: ${message.runtimeType}', name: 'ChatDetailPage');
        _handleWebSocketMessage(message);
      },
      onError: (error) {
        developer.log('WebSocket stream error in ChatDetailPage: $error', name: 'ChatDetailPage');
      },
      onDone: () {
        developer.log('WebSocket stream closed in ChatDetailPage', name: 'ChatDetailPage');
      },
      cancelOnError: false,
    );
    
    developer.log('WebSocket监听器已设置: currentUserId=$_currentUserId, targetUserId=$_targetUserId', name: 'ChatDetailPage');
    
    // 确保WebSocket已连接
    if (_webSocketService.status != LocalWebSocketStatus.connected) {
      developer.log('WebSocket未连接，尝试连接...', name: 'ChatDetailPage');
      _webSocketService.connect();
    } else {
      developer.log('WebSocket已连接', name: 'ChatDetailPage');
    }
  }

  void _handleWebSocketMessage(dynamic message) {
    try {
      developer.log('_handleWebSocketMessage called with: ${message.runtimeType}', name: 'ChatDetailPage');
      
      // 解析消息
      Map<String, dynamic>? messageMap;
      if (message is Map<String, dynamic>) {
        messageMap = message;
        developer.log('Message is already a Map: ${messageMap.keys}', name: 'ChatDetailPage');
      } else if (message is String) {
        try {
          messageMap = Map<String, dynamic>.from(
            jsonDecode(message) as Map
          );
          developer.log('Message parsed from String: ${messageMap.keys}', name: 'ChatDetailPage');
        } catch (e) {
          developer.log('无法解析WebSocket消息: $e', name: 'ChatDetailPage');
          developer.log('Raw message: $message', name: 'ChatDetailPage');
          return;
        }
      } else {
        developer.log('Unknown message type: ${message.runtimeType}', name: 'ChatDetailPage');
        return;
      }

      // 检查是否是状态消息
      if (messageMap['type'] == 'status') {
        developer.log('WebSocket状态: ${messageMap['status']}', name: 'ChatDetailPage');
        return;
      }

      // 提取消息内容（提前声明，供后续使用）
      final messageContent = messageMap['message']?.toString() ?? messageMap['message_body']?.toString() ?? '';
      
      // 检查是否是通话邀请消息（message_content_type === 4 或 type === "call_invite"）
      final messageContentType = messageMap['message_content_type'] ?? messageMap['message_type'];
      final isCallInviteByType = messageContentType == 4;
      
      // 检查消息内容是否是通话邀请格式
      bool isCallInviteByContent = false;
      Map<String, dynamic>? inviteData;
      if (messageContent.isNotEmpty) {
        try {
          final parsed = jsonDecode(messageContent) as Map<String, dynamic>?;
          if (parsed != null && parsed['type'] == 'call_invite') {
            isCallInviteByContent = true;
            inviteData = parsed;
          }
        } catch (e) {
          // 不是 JSON，忽略
        }
      }
      
      // 如果是通话邀请消息，只过滤掉（不显示在聊天界面）
      // 接听对话框由全局 CallManagerService 处理
      if (isCallInviteByType || isCallInviteByContent || messageMap['type'] == 'call_invite') {
        // 检查是否是来自当前好友的邀请（如果在当前好友的聊天页面，可以在这里做特殊处理）
        final fromUserId = messageMap['from_user_id']?.toString() ?? messageMap['from_id']?.toString();
        final isFromTarget = fromUserId != null && _targetUserIds.contains(fromUserId);
        
        if (isFromTarget) {
          developer.log('收到当前好友的通话邀请（由全局服务处理接听对话框）', name: 'ChatDetailPage');
        }
        
        // 通话邀请消息不显示在聊天界面，直接返回
        return;
      }

      // 检查是否是通话取消消息（message_content_type === 5 或 type === "call_cancel"）
      final isCallCancelByType = messageContentType == 5;
      bool isCallCancelByContent = false;
      if (messageContent.isNotEmpty) {
        try {
          final parsed = jsonDecode(messageContent) as Map<String, dynamic>?;
          if (parsed != null && parsed['type'] == 'call_cancel') {
            isCallCancelByContent = true;
          }
        } catch (e) {
          // 不是 JSON，忽略
        }
      }
      
      // 如果是通话取消消息，静默处理，不显示在聊天界面
      if (isCallCancelByType || isCallCancelByContent || messageMap['type'] == 'call_cancel') {
        developer.log('收到通话取消消息，静默处理（不显示在聊天界面）', name: 'ChatDetailPage');
        // 通话取消消息是系统消息，不应该显示在聊天界面
        return;
      }

      // 检查消息是否与当前聊天相关
      final fromUserId = messageMap['from_user_id']?.toString() ?? messageMap['from_id']?.toString();
      final toUserId = messageMap['to_user_id']?.toString() ?? messageMap['to_id']?.toString();
      final messageId = messageMap['message_id']?.toString();
      final messageType = messageMap['message_content_type'] ?? messageMap['message_type'] ?? messageMap['chat_type'] ?? 1;
      final timestamp = messageMap['timestamp_ms'] ?? messageMap['timestamp'] ?? messageMap['message_time'];
      
      // 提取文件/图片相关字段
      String? fileUrl;
      String? fileName;
      String? fileType;
      
      // 从 extra 字段中解析文件信息
      if (messageMap['extra'] != null) {
        try {
          final extra = messageMap['extra'];
          Map<String, dynamic>? extraMap;
          if (extra is String) {
            extraMap = Map<String, dynamic>.from(jsonDecode(extra) as Map);
          } else if (extra is Map) {
            extraMap = Map<String, dynamic>.from(extra);
          }
          
          if (extraMap != null) {
            fileUrl = extraMap['file_url']?.toString();
            fileName = extraMap['file_name']?.toString();
            fileType = extraMap['file_type']?.toString();
          }
        } catch (e) {
          developer.log('解析 extra 字段失败: $e', name: 'ChatDetailPage');
        }
      }
      
      // 如果 message_content_type 是图片(2)或文件(3)，且 message_body 是 URL，使用它作为 fileUrl
      if ((messageType == 2 || messageType == 3) && messageContent.isNotEmpty) {
        final trimmedContent = messageContent.trim();
        // 检查是否是 URL（包括相对路径和绝对路径）
        if (trimmedContent.startsWith('http://') || 
            trimmedContent.startsWith('https://') || 
            trimmedContent.startsWith('/api/upload/') ||
            trimmedContent.startsWith('/upload/') ||
            trimmedContent.startsWith('data:image/')) {
          // 如果 extra 中没有 file_url，使用 message_body 作为 fileUrl
          if (fileUrl == null || fileUrl.isEmpty) {
            fileUrl = trimmedContent;
          }
        }
      }
      
      // 如果 fileUrl 是相对路径，构建完整 URL
      if (fileUrl != null && (fileUrl!.startsWith('/api/upload/') || fileUrl!.startsWith('/upload/'))) {
        // 构建完整 URL：baseUrl + 路径
        final baseUrl = AppConfig.baseUrl;
        final port = AppConfig.serverPort;
        // 确保路径以 /api/upload/ 或 /upload/ 开头
        if (fileUrl!.startsWith('/upload/')) {
          fileUrl = '$baseUrl:$port/api$fileUrl';
        } else {
          fileUrl = '$baseUrl:$port$fileUrl';
        }
      }
      
      // 记录文件信息（用于调试）
      if (messageType == 2 || messageType == 3) {
        developer.log(
          '文件消息: messageType=$messageType, fileUrl=$fileUrl, fileName=$fileName, fileType=$fileType',
          name: 'ChatDetailPage',
        );
      }
      
      developer.log('提取的消息字段: fromUserId=$fromUserId, toUserId=$toUserId, messageId=$messageId, messageContent=$messageContent, messageType=$messageType', name: 'ChatDetailPage');
      
      // 更新当前用户ID（确保是最新的）
      _updateCurrentUserId();
      
      // 检查是否是当前好友的消息
      // 参考 Tauri 代码的匹配逻辑：使用所有可能的ID进行匹配
      // 对于接收的消息：from_user_id 应该是目标用户，to_user_id 应该是当前用户
      // 对于发送的消息：from_user_id 应该是当前用户，to_user_id 应该是目标用户
      
      if (fromUserId == null || toUserId == null) {
        developer.log('消息缺少必要的用户ID，忽略: fromUserId=$fromUserId, toUserId=$toUserId', name: 'ChatDetailPage');
        return;
      }
      
      // 标准化ID（去除空格，统一格式）
      final normalizedFromUserId = fromUserId.trim();
      final normalizedToUserId = toUserId.trim();
      
      // 检查 from_user_id 或 to_user_id 是否匹配目标用户
      final isFromTarget = _targetUserIds.any((id) => normalizedFromUserId == id.trim());
      final isToTarget = _targetUserIds.any((id) => normalizedToUserId == id.trim());
      
      // 检查 from_user_id 或 to_user_id 是否匹配当前用户
      final isFromMe = _currentUserIds.any((id) => normalizedFromUserId == id.trim());
      final isToMe = _currentUserIds.any((id) => normalizedToUserId == id.trim());
      
      // 调试日志
      developer.log(
        '检查消息是否相关: messageId=$messageId, fromUserId=$fromUserId, toUserId=$toUserId, currentUserIds=$_currentUserIds, targetUserIds=$_targetUserIds, isFromTarget=$isFromTarget, isToTarget=$isToTarget, isFromMe=$isFromMe, isToMe=$isToMe',
        name: 'ChatDetailPage',
      );
      
      // 消息必须满足以下条件之一（参考 Tauri 代码）：
      // 1. 好友发送给我（from_target && to_current）
      // 2. 我发送给好友（from_current && to_target）
      final isRelevant = (isFromTarget && isToMe) || (isFromMe && isToTarget);
      
      developer.log('isRelevant=$isRelevant (isFromTarget=$isFromTarget && isToMe=$isToMe) || (isFromMe=$isFromMe && isToTarget=$isToTarget)', name: 'ChatDetailPage');
      
      if (!isRelevant) {
        // 不是当前聊天的消息，忽略
        developer.log(
          '消息不相关，忽略: from=$fromUserId, to=$toUserId, current=$_currentUserId, target=$_targetUserId, targetNum=$_targetUserIdNum, targetUsername=$_targetUsername',
          name: 'ChatDetailPage',
        );
        return;
      }
      
      developer.log('消息相关，继续处理', name: 'ChatDetailPage');

      // 检查消息是否已存在（避免重复）
      if (messageId != null && _messages.any((msg) => msg.messageId == messageId)) {
        developer.log('消息已存在，跳过: $messageId', name: 'ChatDetailPage');
        return;
      }

      // 创建ChatMessage
      final isMe = isFromMe;
      DateTime messageTime;
      if (timestamp != null) {
        if (timestamp is int) {
          messageTime = DateTime.fromMillisecondsSinceEpoch(timestamp);
        } else if (timestamp is String) {
          messageTime = DateTime.tryParse(timestamp) ?? DateTime.now();
        } else {
          messageTime = DateTime.now();
        }
      } else {
        messageTime = DateTime.now();
      }

      // 检查消息内容是否为空
      if (messageContent.isEmpty) {
        developer.log('消息内容为空，跳过: messageId=$messageId', name: 'ChatDetailPage');
        return;
      }

      final chatMessage = ChatMessage(
        content: messageContent,
        isMe: isMe,
        timestamp: messageTime,
        isSending: false,
        messageId: messageId,
        fromUserId: fromUserId,
        toUserId: toUserId,
        messageType: messageType is int ? messageType : 1,
        status: 1,
        fileUrl: fileUrl,
        fileName: fileName,
        fileType: fileType,
      );

      developer.log('准备添加消息到UI: messageId=$messageId, content=$messageContent, isMe=$isMe, mounted=$mounted', name: 'ChatDetailPage');

      if (mounted) {
        setState(() {
          _messages.add(chatMessage);
          developer.log('setState 调用，消息已添加到列表，当前消息数: ${_messages.length}', name: 'ChatDetailPage');
        });
        
        // 保存到本地存储
        _saveMessagesToLocal();
        
        // 滚动到底部
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (_scrollController.hasClients) {
            _scrollController.animateTo(
              _scrollController.position.maxScrollExtent,
              duration: const Duration(milliseconds: 300),
              curve: Curves.easeOut,
            );
            developer.log('已滚动到底部', name: 'ChatDetailPage');
          } else {
            developer.log('ScrollController 没有客户端', name: 'ChatDetailPage');
          }
        });
        
        developer.log('收到WebSocket消息并已添加到UI: messageId=$messageId, 总消息数=${_messages.length}', name: 'ChatDetailPage');
      } else {
        developer.log('Widget 未挂载，无法更新UI', name: 'ChatDetailPage');
      }
    } catch (e) {
      developer.log('处理WebSocket消息失败: $e', name: 'ChatDetailPage');
    }
  }

  Future<void> _saveMessagesToLocal() async {
    if (_currentUserId == null || _messages.isEmpty) return;
    
    try {
      await _messageStorageService.saveMessages(_currentUserId!, _messages);
    } catch (e) {
      developer.log('保存消息到本地失败: $e', name: 'ChatDetailPage');
    }
  }

  /// 清理当前聊天的本地缓存
  Future<void> _clearLocalCache() async {
    _updateCurrentUserId();
    if (_currentUserId == null) {
      context.showError('无法获取用户ID');
      return;
    }

    // 显示确认对话框
    final confirmed = await showDialog<bool>(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('清理聊天记录'),
        content: Text('确定要清理与 ${widget.friend.displayName} 的聊天记录吗？此操作不可恢复。'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(false),
            child: const Text('取消'),
          ),
          TextButton(
            onPressed: () => Navigator.of(context).pop(true),
            style: TextButton.styleFrom(
              foregroundColor: Colors.red,
            ),
            child: const Text('确定清理'),
          ),
        ],
      ),
    );

    if (confirmed != true) {
      return;
    }

    try {
      // 清理本地存储中与当前好友相关的消息
      // 由于存储是按用户ID存储的，我们需要先加载所有消息，过滤掉当前好友的消息，然后保存回去
      final allMessages = await _messageStorageService.loadMessages(_currentUserId!);
      
      // 过滤掉与当前好友相关的消息（使用ID集合进行匹配）
      final remainingMessages = allMessages.where((msg) {
        if (msg.fromUserId == null || msg.toUserId == null) {
          return true; // 保留没有用户ID的消息（可能是旧数据）
        }
        
        final normalizedFromUserId = msg.fromUserId!.trim();
        final normalizedToUserId = msg.toUserId!.trim();
        
        // 检查 from_user_id 或 to_user_id 是否匹配目标用户
        final isFromTarget = _targetUserIds.any((id) => normalizedFromUserId == id.trim());
        final isToTarget = _targetUserIds.any((id) => normalizedToUserId == id.trim());
        
        // 检查 from_user_id 或 to_user_id 是否匹配当前用户
        final isFromMe = _currentUserIds.any((id) => normalizedFromUserId == id.trim());
        final isToMe = _currentUserIds.any((id) => normalizedToUserId == id.trim());
        
        // 保留不是与当前好友相关的消息
        return !((isFromTarget && isToMe) || (isFromMe && isToTarget));
      }).toList();

      // 保存剩余的消息
      if (remainingMessages.isEmpty) {
        // 如果没有剩余消息，直接清理
        await _messageStorageService.clearMessages(_currentUserId!);
      } else {
        // 保存剩余的消息
        await _messageStorageService.saveMessages(_currentUserId!, remainingMessages);
      }

      // 清空当前显示的消息列表
      if (mounted) {
        setState(() {
          _messages.clear();
        });
        developer.log('已清理与 ${widget.friend.displayName} 的聊天记录', name: 'ChatDetailPage');
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text('聊天记录已清理'),
            duration: Duration(seconds: 2),
          ),
        );
      }
    } catch (e) {
      developer.log('清理聊天记录失败: $e', name: 'ChatDetailPage');
      if (mounted) {
        context.showError('清理聊天记录失败: $e');
      }
    }
  }

  @override
  void dispose() {
    _websocketSubscription?.cancel();
    _saveMessagesToLocal(); // 保存消息到本地
    _messageController.dispose();
    _scrollController.dispose();
    super.dispose();
  }

  /// 处理通话邀请消息
  void _handleCallInvite(Map<String, dynamic> messageMap, Map<String, dynamic>? inviteDataFromContent) {
    try {
      developer.log('收到通话邀请消息', name: 'ChatDetailPage');
      
      // 提取邀请数据
      Map<String, dynamic> inviteData;
      if (inviteDataFromContent != null) {
        inviteData = inviteDataFromContent;
      } else if (messageMap['type'] == 'call_invite') {
        inviteData = messageMap;
      } else {
        // 尝试从 message 字段解析
        final messageContent = messageMap['message']?.toString() ?? messageMap['message_body']?.toString() ?? '';
        if (messageContent.isNotEmpty) {
          try {
            inviteData = jsonDecode(messageContent) as Map<String, dynamic>;
          } catch (e) {
            developer.log('无法解析通话邀请内容: $e', name: 'ChatDetailPage');
            return;
          }
        } else {
          developer.log('通话邀请消息缺少内容', name: 'ChatDetailPage');
          return;
        }
      }
      
      // 检查邀请是否已过期
      final timestamp = inviteData['timestamp'] ?? messageMap['timestamp_ms'] ?? messageMap['timestamp'];
      final timeout = inviteData['timeout'] ?? 30;
      final messageTimestamp = timestamp is int ? timestamp : DateTime.now().millisecondsSinceEpoch;
      
      // 检查是否过期
      final now = DateTime.now().millisecondsSinceEpoch;
      final expireTime = messageTimestamp + (timeout * 1000);
      if (now > expireTime) {
        developer.log('通话邀请已过期，忽略', name: 'ChatDetailPage');
        return;
      }
      
      // 检查是否是来自当前好友的邀请
      final fromUserId = messageMap['from_user_id']?.toString() ?? messageMap['from_id']?.toString();
      if (fromUserId == null) {
        developer.log('通话邀请消息缺少发送者ID', name: 'ChatDetailPage');
        return;
      }
      
      // 检查是否匹配当前好友
      final isFromTarget = _targetUserIds.contains(fromUserId);
      if (!isFromTarget) {
        developer.log('通话邀请不是来自当前好友，忽略（由全局通话服务处理）', name: 'ChatDetailPage');
        return;
      }
      
      // 创建通话邀请对象
      final callInvite = CallInvite(
        fromUserId: fromUserId,
        fromUserName: widget.friend?.displayName ?? widget.friend?.username ?? fromUserId,
        isVoiceOnly: inviteData['isVoiceOnly'] ?? inviteData['is_voice_only'] ?? false,
        messageId: messageMap['message_id']?.toString() ?? DateTime.now().millisecondsSinceEpoch.toString(),
        timeout: timeout,
        timestamp: messageTimestamp,
      );
      
      // 显示接听对话框
      if (mounted) {
        showDialog(
          context: context,
          barrierDismissible: false,
          builder: (context) => CallInviteDialog(
            invite: callInvite,
            friend: widget.friend,
            onAccept: () {
              _acceptCall(callInvite);
            },
            onReject: () {
              developer.log('用户拒绝通话邀请', name: 'ChatDetailPage');
            },
          ),
        );
      }
    } catch (e) {
      developer.log('处理通话邀请失败: $e', name: 'ChatDetailPage');
    }
  }
  
  /// 接听通话
  void _acceptCall(CallInvite invite) {
    developer.log('接听通话: ${invite.isVoiceOnly ? "语音" : "视频"}', name: 'ChatDetailPage');
    
    _updateCurrentUserId();
    if (_currentUserId == null) {
      context.showError('无法获取用户ID');
      return;
    }
    
    // 导航到视频通话页面（接听模式）
    Navigator.of(context).push(
      MaterialPageRoute(
        builder: (context) => VideoCallPage(
          targetUserId: invite.fromUserId,
          targetName: invite.fromUserName,
          currentUserId: _currentUserId!,
          isVoiceOnly: invite.isVoiceOnly,
        ),
      ),
    );
  }
  
  /// 发送通话邀请
  Future<void> _sendCallInvite(bool isVoiceOnly) async {
    _updateCurrentUserId();
    if (_currentUserId == null) {
      context.showError('无法获取用户ID');
      return;
    }
    
    final targetId = _targetUserId ?? widget.friend.username;
    if (targetId.isEmpty) {
      context.showError('无法获取目标用户ID');
      return;
    }
    
    try {
      final serviceLocator = ServiceLocator();
      final chatRepository = ChatRepository(serviceLocator.apiService);
      
      // 发送通话邀请
      final response = await chatRepository.sendCallInvite(
        fromId: _currentUserId!,
        toId: targetId,
        isVoiceOnly: isVoiceOnly,
        timeout: 30,
      );
      
      if (response.success) {
        developer.log('通话邀请已发送', name: 'ChatDetailPage');
        
        // 打开视频通话页面（拨打模式）
        Navigator.of(context).push(
          MaterialPageRoute(
            builder: (context) => VideoCallPage(
              targetUserId: targetId,
              targetName: widget.friend.displayName,
              currentUserId: _currentUserId!,
              isVoiceOnly: isVoiceOnly,
            ),
          ),
        );
      } else {
        context.showError('发送通话邀请失败: ${response.message}');
      }
    } catch (e) {
      developer.log('发送通话邀请失败: $e', name: 'ChatDetailPage');
      context.showError('发送通话邀请失败: $e');
    }
  }

  Future<void> _sendMessage() async {
    final text = _messageController.text.trim();
    if (text.isEmpty || _isSending) return;

    // 获取当前用户信息
    final authViewModel = context.read<AuthViewModel>();
    final currentUser = authViewModel.currentUser;
    if (currentUser == null) {
      context.showError('请先登录');
      return;
    }

    // 获取发送者和接收者的 open_id
    // 发送者：优先使用 open_id，否则使用 username
    final fromId = currentUser.openId ?? currentUser.username;
    
    // 接收者：从好友信息中获取，优先使用 open_id（如果 FriendModel 有的话），否则使用 username
    // 注意：FriendModel 目前可能没有 open_id，暂时使用 username
    final toId = widget.friend.username;

    if (fromId.isEmpty || toId.isEmpty) {
      context.showError('无法获取用户ID');
      return;
    }

    // 创建临时消息ID
    final tempMessageId = 'temp_${DateTime.now().millisecondsSinceEpoch}';
    
    setState(() {
      _isSending = true;
      // 先添加到本地列表，显示发送中状态
      _messages.add(ChatMessage(
        content: text,
        isMe: true,
        timestamp: DateTime.now(),
        isSending: true,
        messageId: tempMessageId,
        fromUserId: fromId,
        toUserId: toId,
        messageType: 1,
        status: 0, // 发送中
      ));
    });
    
    // 保存到本地（发送中的消息也保存）
    _saveMessagesToLocal();

    _messageController.clear();
    
    // 滚动到底部
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (_scrollController.hasClients) {
        _scrollController.animateTo(
          _scrollController.position.maxScrollExtent,
          duration: const Duration(milliseconds: 300),
          curve: Curves.easeOut,
        );
      }
    });

    try {
      // 获取 ChatRepository
      final serviceLocator = ServiceLocator();
      final chatRepository = ChatRepository(serviceLocator.apiService);
      
      // 发送消息
      final response = await chatRepository.sendSingleMessage(
        fromId: fromId,
        toId: toId,
        messageBody: text,
        messageContentType: 1, // 文本消息
      );

      setState(() {
        _isSending = false;
        // 更新最后一条消息的状态
        if (_messages.isNotEmpty) {
          final lastMessage = _messages.last;
          if (lastMessage.isMe && lastMessage.isSending == true) {
            // 获取响应中的消息ID（如果有）
            final responseMessageId = response.data?.id?.toString() ?? 
                                     response.data?.chatId?.toString() ?? 
                                     tempMessageId;
            
            _messages[_messages.length - 1] = ChatMessage(
              content: lastMessage.content,
              isMe: lastMessage.isMe,
              timestamp: lastMessage.timestamp,
              isSending: false,
              messageId: responseMessageId,
              fromUserId: lastMessage.fromUserId,
              toUserId: lastMessage.toUserId,
              messageType: lastMessage.messageType,
              status: 1, // 已发送
            );
          }
        }
      });
      
      // 保存到本地
      _saveMessagesToLocal();

      // 检查响应状态
      if (response.success) {
        // 发送成功，显示成功提示（可选）
        // context.showSuccess('消息已发送');
      } else {
        // 发送失败，显示错误信息
        final errorMessage = response.message.isNotEmpty 
            ? response.message 
            : '发送消息失败（错误代码: ${response.code}）';
        context.showError(errorMessage);
        // 如果发送失败，移除本地消息
        setState(() {
          if (_messages.isNotEmpty && _messages.last.isSending == true) {
            _messages.removeLast();
          }
        });
      }
    } catch (e) {
      setState(() {
        _isSending = false;
        // 如果发送失败，移除本地消息
        if (_messages.isNotEmpty && _messages.last.isSending == true) {
          _messages.removeLast();
        }
      });
      context.showError('发送消息失败: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 0,
        title: Row(
          children: [
            CachedAvatar(
              imageUrl: widget.friend.avatar,
              name: widget.friend.displayName,
              size: 40,
              borderRadius: 20,
            ),
            const SizedBox(width: 12),
            Expanded(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    widget.friend.displayName,
                    style: const TextStyle(
                      fontSize: 17,
                      fontWeight: FontWeight.w600,
                      color: Colors.black87,
                    ),
                    overflow: TextOverflow.ellipsis,
                  ),
                  // 可以在这里添加在线状态等
                ],
              ),
            ),
          ],
        ),
        actions: [
          // 语音通话按钮
          IconButton(
            icon: const Icon(Icons.phone),
            tooltip: '语音通话',
            onPressed: () => _sendCallInvite(true),
          ),
          // 视频通话按钮
          IconButton(
            icon: const Icon(Icons.videocam),
            tooltip: '视频通话',
            onPressed: () => _sendCallInvite(false),
          ),
          PopupMenuButton<String>(
            icon: const Icon(Icons.more_vert),
            onSelected: (value) {
              if (value == 'clear_cache') {
                _clearLocalCache();
              } else if (value == 'more') {
                ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(content: Text('更多功能开发中')),
                );
              }
            },
            itemBuilder: (context) => [
              const PopupMenuItem(
                value: 'clear_cache',
                child: Row(
                  children: [
                    Icon(Icons.delete_outline, size: 20),
                    SizedBox(width: 12),
                    Text('清理聊天记录'),
                  ],
                ),
              ),
              const PopupMenuItem(
                value: 'more',
                child: Row(
                  children: [
                    Icon(Icons.more_horiz, size: 20),
                    SizedBox(width: 12),
                    Text('更多功能'),
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
      body: Column(
        children: [
          // 消息列表
          Expanded(
            child: Container(
              color: const Color(0xFFEDEDED), // 浅灰色背景，类似 Tauri 版本
              child: _messages.isEmpty
                  ? Center(
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Icon(
                            Icons.chat_bubble_outline,
                            size: 64,
                            color: Colors.grey[400],
                          ),
                          const SizedBox(height: 16),
                          Text(
                            '还没有消息，开始聊天吧',
                            style: TextStyle(
                              fontSize: 16,
                              color: Colors.grey[600],
                            ),
                          ),
                        ],
                      ),
                    )
                  : ListView.builder(
                      controller: _scrollController,
                      padding: const EdgeInsets.symmetric(
                        horizontal: 20,
                        vertical: 20,
                      ),
                      reverse: false,
                      itemCount: _messages.length,
                      itemBuilder: (context, index) {
                        final message = _messages[index];
                        return _buildMessageBubble(message);
                      },
                    ),
            ),
          ),
          // 输入框
          Container(
            decoration: BoxDecoration(
              color: Colors.white,
              boxShadow: [
                BoxShadow(
                  color: Colors.black.withOpacity(0.05),
                  blurRadius: 10,
                  offset: const Offset(0, -2),
                ),
              ],
            ),
            child: SafeArea(
              child: Padding(
                padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: [
                    // 添加按钮
                    Material(
                      color: Colors.transparent,
                      child: InkWell(
                        onTap: () {
                          // TODO: 显示更多选项（图片、文件等）
                          ScaffoldMessenger.of(context).showSnackBar(
                            const SnackBar(content: Text('更多功能开发中')),
                          );
                        },
                        borderRadius: BorderRadius.circular(20),
                        child: Container(
                          padding: const EdgeInsets.all(8),
                          child: Icon(
                            Icons.add_circle_outline,
                            color: Colors.grey[700],
                            size: 28,
                          ),
                        ),
                      ),
                    ),
                    const SizedBox(width: 4),
                    // 输入框
                    Expanded(
                      child: Container(
                        constraints: const BoxConstraints(
                          maxHeight: 120,
                        ),
                        decoration: BoxDecoration(
                          color: Colors.grey[100],
                          borderRadius: BorderRadius.circular(24),
                        ),
                        child: TextField(
                          controller: _messageController,
                          decoration: InputDecoration(
                            hintText: '输入消息...',
                            hintStyle: TextStyle(
                              color: Colors.grey[500],
                              fontSize: 15,
                            ),
                            border: InputBorder.none,
                            contentPadding: const EdgeInsets.symmetric(
                              horizontal: 16,
                              vertical: 10,
                            ),
                          ),
                          style: const TextStyle(fontSize: 15),
                          maxLines: null,
                          minLines: 1,
                          textInputAction: TextInputAction.send,
                          onSubmitted: (_) => _sendMessage(),
                        ),
                      ),
                    ),
                    const SizedBox(width: 8),
                    // 发送按钮
                    Material(
                      color: Theme.of(context).colorScheme.primary,
                      borderRadius: BorderRadius.circular(20),
                      child: InkWell(
                        onTap: _isSending ? null : _sendMessage,
                        borderRadius: BorderRadius.circular(20),
                        child: Container(
                          padding: const EdgeInsets.all(10),
                          child: _isSending
                              ? SizedBox(
                                  width: 20,
                                  height: 20,
                                  child: CircularProgressIndicator(
                                    strokeWidth: 2,
                                    valueColor: AlwaysStoppedAnimation<Color>(
                                      Colors.white,
                                    ),
                                  ),
                                )
                              : const Icon(
                                  Icons.send,
                                  color: Colors.white,
                                  size: 20,
                                ),
                        ),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget _buildMessageBubble(ChatMessage message) {
    return TweenAnimationBuilder<double>(
      tween: Tween(begin: 0.0, end: 1.0),
      duration: const Duration(milliseconds: 200),
      curve: Curves.easeOut,
      builder: (context, value, child) {
        return Opacity(
          opacity: value,
          child: Transform.translate(
            offset: Offset(0, 10 * (1 - value)),
            child: child,
          ),
        );
      },
      child: Align(
        alignment: message.isMe ? Alignment.centerRight : Alignment.centerLeft,
        child: Container(
          margin: const EdgeInsets.only(bottom: 12),
          constraints: BoxConstraints(
            maxWidth: MediaQuery.of(context).size.width * 0.7,
          ),
          child: Row(
          mainAxisAlignment:
              message.isMe ? MainAxisAlignment.end : MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            if (!message.isMe) ...[
              CachedAvatar(
                imageUrl: widget.friend.avatar,
                name: widget.friend.displayName,
                size: 36,
                borderRadius: 18,
              ),
              const SizedBox(width: 10),
            ],
            Flexible(
              child: Column(
                crossAxisAlignment: message.isMe
                    ? CrossAxisAlignment.end
                    : CrossAxisAlignment.start,
                children: [
                  // 时间显示在消息上方
                  Padding(
                    padding: EdgeInsets.only(
                      bottom: 6,
                      left: message.isMe ? 0 : 2,
                      right: message.isMe ? 2 : 0,
                    ),
                    child: Text(
                      _formatTime(message.timestamp),
                      style: TextStyle(
                        color: Colors.grey[600],
                        fontSize: 11,
                        fontWeight: FontWeight.w400,
                        letterSpacing: 0.2,
                      ),
                    ),
                  ),
                  // 消息气泡
                  Container(
                    padding: const EdgeInsets.symmetric(
                      horizontal: 12,
                      vertical: 8,
                    ),
                    decoration: BoxDecoration(
                      color: message.isMe
                          ? Theme.of(context).colorScheme.primary
                          : Colors.white,
                      borderRadius: BorderRadius.only(
                        topLeft: const Radius.circular(16),
                        topRight: const Radius.circular(16),
                        bottomLeft: Radius.circular(message.isMe ? 16 : 4),
                        bottomRight: Radius.circular(message.isMe ? 4 : 16),
                      ),
                      boxShadow: message.isMe
                          ? [
                              BoxShadow(
                                color: Colors.black.withOpacity(0.05),
                                blurRadius: 4,
                                offset: const Offset(0, 1),
                              ),
                            ]
                          : null,
                    ),
                    child: Row(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children: [
                        Flexible(
                          child: MarkdownMessage(
                            content: message.content,
                            isSent: message.isMe,
                            fileUrl: message.fileUrl,
                            fileName: message.fileName,
                            fileType: message.fileType,
                            messageContentType: message.messageType,
                            backgroundColor: message.isMe
                                ? Theme.of(context).colorScheme.primary
                                : Colors.white,
                            textColor: message.isMe ? Colors.white : Colors.black87,
                          ),
                        ),
                        // 发送状态指示（仅自己发送的消息）
                        if (message.isMe) ...[
                          const SizedBox(width: 4),
                          _buildMessageStatus(message),
                        ],
                      ],
                    ),
                  ),
                ],
              ),
            ),
            if (message.isMe) ...[
              const SizedBox(width: 10),
              CachedAvatar(
                imageUrl: null,
                name: '我',
                size: 36,
                borderRadius: 18,
              ),
            ],
          ],
        ),
      ),
      ),
    );
  }

  /// 构建消息状态指示器
  Widget _buildMessageStatus(ChatMessage message) {
    if (message.isSending == true) {
      // 发送中
      return SizedBox(
        width: 12,
        height: 12,
        child: CircularProgressIndicator(
          strokeWidth: 1.5,
          valueColor: AlwaysStoppedAnimation<Color>(
            Colors.white.withOpacity(0.7),
          ),
        ),
      );
    } else if (message.status == 1) {
      // 已发送
      return Icon(
        Icons.done,
        size: 14,
        color: Colors.white.withOpacity(0.7),
      );
    } else if (message.status == 2) {
      // 已读
      return Icon(
        Icons.done_all,
        size: 14,
        color: Colors.white.withOpacity(0.9),
      );
    } else {
      // 发送失败或其他状态
      return Icon(
        Icons.error_outline,
        size: 14,
        color: Colors.white.withOpacity(0.7),
      );
    }
  }

  String _formatTime(DateTime time) {
    final now = DateTime.now();
    final difference = now.difference(time);

    if (difference.inDays == 0) {
      // 今天
      return '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
    } else if (difference.inDays == 1) {
      // 昨天
      return '昨天 ${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
    } else if (difference.inDays < 7) {
      // 一周内
      final weekdays = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
      return '${weekdays[time.weekday - 1]} ${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
    } else {
      // 更早
      return '${time.month}/${time.day} ${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
    }
  }
}


